home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / equel / cvar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-12-31  |  5.4 KB  |  306 lines

  1. # include    <stdio.h>
  2. # include    "constants.h"
  3. # include    "globals.h"
  4. # include    <sccs.h>
  5.  
  6. SCCSID(@(#)cvar.c    8.1    12/31/84)
  7.  
  8. /*
  9. **  CVAR -- routines to manipulate the c variable trees
  10. **
  11. **    C variable trees are binary trees of cvar structs,
  12. **    with the c_left < c_right with respect to c_id.
  13. */
  14. /*
  15. **  DECL_CVAR -- Declare a C variable
  16. **
  17. **    Parameters:
  18. **        name -- identifier string (makes its own copy for the tree)
  19. **        type 
  20. **        indir_level -- level of indirection of declaration
  21. **            (- 1 if string)
  22. **        block_level -- 0 - global, else local var
  23. **
  24. **    Returns:
  25. **        none
  26. **
  27. **    Side Effects:
  28. **        allocates a cvar node, and a copy of name, may put a node
  29. **        in a cvar tree (if not previously declared).
  30. **
  31. **    Called By:
  32. **        the c_variable productions of the parser [grammar.y]
  33. */
  34.  
  35.  
  36. decl_cvar(name, type, indir_level, block_level)
  37. char        *name;
  38. int        type;
  39. int        indir_level;
  40. int        block_level;
  41. {
  42.     register struct cvar        *bad_node;
  43.     struct cvar            *dec_var();
  44.  
  45.     if (bad_node = dec_var(name, type, indir_level, block_level,
  46.                 &C_locals, &C_globals))
  47.     {
  48.         yysemerr("re-declared identifier", bad_node->c_id);
  49.         xfree(bad_node->c_id);
  50.         xfree(bad_node);
  51.     }
  52. }
  53.  
  54. /*
  55. **  DECL_FIELD -- Declare a structures field
  56. **
  57. **    Same as decl_cvar() for fields within C records (structs).
  58. **    NOTE : if a !0 is returned from dec_var() (i.e. the field
  59. **    was already declared) the storage for that node is freed
  60. **    but no error has been comitted, as fields may be re-declared.
  61. */
  62.  
  63. decl_field(name, type, indir_level, block_level)
  64. char        *name;
  65. int        type;
  66. int        indir_level;
  67. int        block_level;
  68. {
  69.     register struct cvar        *bad_node;
  70.     struct cvar            *dec_var();
  71.  
  72.     if (bad_node = dec_var(name, type, indir_level, block_level,
  73.                 &F_locals, &F_globals))
  74.     {
  75.         xfree(bad_node->c_id);
  76.         xfree(bad_node);
  77.     }
  78. }
  79. /*
  80. **  DEC_VAR -- declare a C var or field.
  81. **
  82. **    Parameters:
  83. **        same as decl_cvar() & decl_field plus
  84. **        the local and global tree variables.
  85. **
  86. **    Returns:
  87. **        0 -- successful
  88. **        other -- cvar node pointer that couldn't be entered
  89. **            to tree
  90. */
  91.  
  92. struct cvar *
  93. dec_var(name, type, indir_level, block_level, local_tree, global_tree)
  94. char        *name;
  95. int        type, indir_level, block_level;
  96. struct cvar    **local_tree, **global_tree;
  97. {
  98.     register struct cvar        *cvarp;
  99.     register            i;
  100.     char                *salloc();
  101.  
  102.     cvarp = (struct cvar *)nalloc(sizeof *cvarp);
  103.     if (!cvarp)
  104.     {
  105.         yysemerr("unable to allocate space for a variable", name);
  106.         return (0);
  107.     }
  108.     if (!(cvarp->c_id = salloc(name)))
  109.     {
  110.         yysemerr("no space for variable name", name);
  111.         xfree(cvarp);
  112.         return (0);
  113.     }
  114.     cvarp->c_type = type;
  115.     cvarp->c_indir = indir_level;
  116.     cvarp->c_left = cvarp->c_right = 0;
  117.     i = c_enter(cvarp, block_level > 0 ? local_tree : global_tree);
  118.     return (i ? 0 : cvarp);
  119. }
  120. /*
  121. **   C_ENTER -- Enter a cvar node in a cvar tree
  122. **
  123. **    Parameters:
  124. **        node -- the cvar node to insert
  125. **        root -- a pointer to the root pointer
  126. **
  127. **    Returns:
  128. **        1 -- if successful
  129. **        0 -- otherwise (node of same name existed
  130. **
  131. **    Side Effects:
  132. **        If a node of that name didn't exist one is inserted
  133. **
  134. **    Called By:
  135. **        dec_var()
  136. */
  137.  
  138. c_enter(node, root)
  139. struct cvar    *node;
  140. struct cvar    **root;
  141. {
  142.     register char        *name;
  143.     register struct cvar    *n, *r;
  144.  
  145.     r = *root;
  146.     n = node;
  147.     name = n->c_id;
  148.     if (!r)
  149.     {
  150.         *root = n;
  151.         return (1);
  152.     }
  153.     for (;;)
  154.     {
  155.         switch (scompare(name, 0, r->c_id, 0))
  156.         {
  157.             
  158.           case -1 :
  159.             if (!r->c_left)
  160.             {
  161.                 r->c_left = n;
  162.                 return (1);
  163.             }
  164.             r = r->c_left;
  165.             break;
  166.  
  167.           case 0 :
  168.             yysemerr("identifier re-declared", name);
  169.             xfree(name);
  170.             xfree(n);
  171.             return (0);
  172.  
  173.           case 1 :
  174.             if (!r->c_right)
  175.             {
  176.                 r->c_right = n;
  177.                 return (1);
  178.             }
  179.             r = r->c_right;
  180.             break;
  181.         }
  182.     }
  183. }
  184.  
  185.  
  186. /*
  187. **  GET_VAR -- get a cvar node from a local_tree, global_tree pair
  188. **    searching first through the local then the global.
  189. **
  190. **    Parameters:
  191. **        id -- c_id key
  192. **        local_tree -- first tree
  193. **        global_tree -- secomd tree to search
  194. **
  195. **    Returns:
  196. **        0 -- if no node by that name
  197. **        otherwise -- pointer to the node
  198. */
  199.  
  200.  
  201. struct cvar *get_var(id, local_tree, global_tree)
  202. char        *id;
  203. struct cvar    *local_tree, *global_tree;
  204. {
  205.     register char        *name;
  206.     register struct cvar    *tree, *node;
  207.     char            flag;
  208.  
  209.     flag = 0;
  210.     name = id;
  211.     tree = local_tree;
  212.     for ( ; ; )
  213.     {
  214.         for (node = tree; node; )
  215.         {
  216.             switch (scompare(name, 0, node->c_id, 0))
  217.             {
  218.               
  219.               case -1 :
  220.                 if (!node->c_left)
  221.                     break;
  222.                 else
  223.                     node = node->c_left;
  224.                 continue;
  225.  
  226.               case 0 :
  227.                 return (node);
  228.  
  229.               case 1 :
  230.                 if (!node->c_right)
  231.                     break;
  232.                 else
  233.                     node = node->c_right;
  234.                 continue;
  235.             }
  236.             break;
  237.         }
  238.         if (!flag)
  239.         {
  240.             flag += 1;
  241.             tree = global_tree;
  242.         }
  243.         else
  244.             return (0);
  245.     }
  246. }
  247. /*
  248. **  GETCVAR -- get the cvar node for a given identifier
  249. **    Looks first in C_locals, then in C_globals.
  250. **
  251. **    Parameters:
  252. **        id -- name of cvar to look for
  253. **
  254. **    Returns:
  255. **        adress of cvar node if found
  256. **        0 -- otherwise
  257. **
  258. **    Requires:
  259. **        C_locals & C_globals -- to search them
  260. */
  261.  
  262. struct cvar    *
  263. getcvar(id)
  264. char        *id;
  265. {
  266.     return (get_var(id, C_locals, C_globals));
  267. }
  268.  
  269. /*
  270. **  GETFIELD -- Same as getcvar() for structure fields
  271. */
  272.  
  273. struct cvar    *
  274. getfield(id)
  275. char        *id;
  276. {
  277.     return (get_var(id, F_locals, F_globals));
  278. }
  279.  
  280.  
  281. /*
  282. **  FREECVAR & F_CVAR -- Free up storage in a cvar tree
  283. **
  284. **    Freecvar calls f_cvar to free storage for a tree, then
  285. **    0's out the root pointer passed it.
  286. */
  287.  
  288. freecvar(rootp)
  289. struct cvar    **rootp;
  290. {
  291.     f_cvar(*rootp);
  292.     *rootp = 0;
  293. }
  294.  
  295. f_cvar(root)
  296. struct cvar    *root;
  297. {
  298.     if (root)
  299.     {
  300.         f_cvar(root->c_left);
  301.         f_cvar(root->c_right);
  302.         xfree(root->c_id);
  303.         xfree(root);
  304.     }
  305. }
  306.